home *** CD-ROM | disk | FTP | other *** search
/ Delphi Developer's Kit 1996 / Delphi Developer's Kit 1996.iso / power / sprites / mchspbg.pas next >
Pascal/Delphi Source File  |  1995-12-22  |  25KB  |  747 lines

  1. unit MChSpBg;
  2.  
  3. {  
  4.                        Real Time Scaleable Sprites 
  5.                               Components 
  6.                                  for 
  7.                             Borland Delphi
  8.  
  9.                           Copyright 1995 by
  10.                          Marek A. Chmielowski
  11.                          All rights reserved
  12.  
  13. These components and source code is released to the public domain under the condition
  14.  that it will not be used for commercial or "For Profit" ventures. 
  15. This code can be copied, used, and distributed freely providing that it is NOT 
  16. modified, no fee is charged, and it is not used in a package for which a charge 
  17. is made.
  18.  
  19. Please do NOT distribute components or source code if you altered them - 
  20.                     EVEN IF THIS IS ONLY BUG CORRECTION.  
  21. Let me know about the problem and the solution and I will implement it in the 
  22. next version (may be it will be the next version).  
  23. My e-mail:  
  24.                        76360,2775@compuserve.com
  25.  
  26. If you would like to use this component for shareware or commercial application 
  27. please contact me first by mail:
  28.                           
  29.                           Marek Chmielowski
  30.                           5/56 Kozia St.
  31.                           Warsaw 00-070
  32.                           Poland   
  33.                                   or
  34.  
  35.                           Marek Chmielowski
  36.                           10005 Broad St. 
  37.                           Bethesda, MD 20814
  38.                           USA
  39.  
  40.                           
  41. }
  42.  
  43. interface
  44.  
  45. uses
  46.   SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
  47.   Forms, Dialogs, ExtCtrls, Buttons, StdCtrls;
  48.  
  49. const
  50.   NulPoint: TPoint=(x:0;y:0);
  51.   NulRect: TRect=(left:0;top:0;right:0;bottom:0);
  52. const
  53.   BgrMaxSpriteNum = 100;
  54.  
  55. type
  56.   TBgrOnInit = procedure;
  57.   TBgrSpriteList = array[1..BgrMaxSpriteNum] of TGraphicControl;
  58.   TDirtyReg = record
  59.     Old: TRect;
  60.     New: TRect;
  61.     end;
  62.  
  63. type
  64.   TMChSpriteBgr = class(TImage)
  65.     { Public declarations or Published if $M+ }
  66.   private
  67.     { Private declarations }
  68.     FBgrSavedOnIdle: TIdleEvent;
  69.     FBgrInitialized: Boolean;
  70.     FBgrSavedBgr: TBitmap;
  71.     FBgrScreenBuf: TBitmap;
  72.     FBgrSpritesRunning: Boolean;
  73.     FBgrPause: Boolean;
  74.     FBgrRespondToMouse: Boolean;
  75.     FBgrIdleCntr: Cardinal;
  76.     FBgrStartIdle: TDateTime;
  77.     FBgrCntsPerSec: double;
  78.     FBgrSpriteList:TBgrSpriteList;
  79.     FBgrNumOfSprites: Cardinal;
  80.     FBgrSprTmp: TGraphicControl;
  81.     FBgrSprHitted: TGraphicControl;
  82.     FBgrSprHittedWas: TGraphicControl;
  83.     FBgrSprHittedIndex: Cardinal;
  84.     FBgrSprHittedIndexWas: Cardinal;
  85.     FBgrSprHittedAt: TPoint;
  86.     FBgrSprWasHitted: Boolean;
  87.     FBgrSprCaptured: TGraphicControl;
  88.     FBgrSprCapturedIndexWas: Cardinal;
  89.     FBgrSpriteCaptured: Boolean;
  90.     FBgrSearchSprts: Boolean;
  91.     FBgrOnInit: TBgrOnInit;
  92.     FBgrInAppIdle: Boolean;
  93.   protected
  94.     { Protected declarations }
  95.     procedure BgrFree;
  96.   public
  97.     { Public declarations }
  98.     constructor Create(AOwner: TComponent); override;
  99.     destructor  Destroy; override;
  100.     procedure BgrInit;
  101.     procedure BgrRestoreBgr;
  102.     procedure BgrRestoreScreen;
  103.     procedure BgrSetBackground(Bg: TBitmap);
  104.     procedure BgrUpdateDirtyReg(Dr: TDirtyReg);
  105.     procedure BgrUpdateDirtyRegToCanvas(Dr: TDirtyReg);
  106.     procedure BgrEraseBufRect(Rc:TRect);
  107.     procedure BgrScreenBufDrawMaskPaint(LeftTop: TPoint; BitMask, Bitmp: TBitmap);
  108.     procedure BgrScreenBufStretchMaskPaint(RectToPaintTo: TRect; BitMask, Bitmp: TBitmap);
  109.     procedure BgrScreenBufDrawRect(LeftTop: TPoint; Bitmp: TBitmap);
  110.     procedure BgrScreenBufGetRect(RectCopyTo: TRect; BitmpCopyTo: TBitmap; RectCopyFrom: TRect);
  111.     procedure BgrHideInBuf;
  112.     procedure BgrShowInBuf(JT: TDateTime);
  113.     procedure BgrUpdateBgrCanvas;
  114.     procedure BgrGetAllSprites(BgrParent: TComponent);
  115.     function  BgrAddTopSpr(Spr: TGraphicControl): Boolean;
  116.     procedure BgrDeleteTopSpr;
  117.     procedure BgrSprExchangeZ(Spr1, Spr2: TGraphicControl);
  118.     procedure BgrSprShiftZ(SprFrom, SprDest: TGraphicControl);
  119.     procedure BgrSprExchangeToTop(Spr: TGraphicControl);
  120.     procedure BgrSprShiftToTop(Spr: TGraphicControl);
  121.     procedure BgrSprIndexExchangeZ(SprI1, SprI2: Cardinal);
  122.     procedure BgrSprIndexShiftZ(SprIFrom, SprIDest: Cardinal);
  123.     procedure BgrSprIndexExchangeToTop(SprI: Cardinal);
  124.     procedure BgrSprIndexShiftToTop(SprI: Cardinal);
  125.     procedure BgrCollisionCheck(AtTime: TDateTime);
  126.     procedure BgrAppIdle(Sender: TObject; var Done: Boolean);
  127.     property  BgrPause: Boolean read FBgrPause write FBgrPause default False;
  128.     property  BgrBackground: TBitmap read FBgrSavedBgr write BgrSetBackground;
  129.     property  BgrNumOfSprites: Cardinal read FBgrNumOfSprites;
  130.     property  BgrCntsPerSec: double read FBgrCntsPerSec;
  131.     property  BgrIdleCntr: Cardinal read FBgrIdleCntr;
  132.     property  BgrOnInit: TBgrOnInit read FBgrOnInit write FBgrOnInit;
  133.     property  BgrInAppIdle: Boolean read FBgrInAppIdle;
  134.     property  BgrSprHitted: TGraphicControl read FBgrSprHitted;
  135.     property  BgrSprHittedWas: TGraphicControl read FBgrSprHittedWas;
  136.     property  BgrSprHittedIndex: Cardinal read FBgrSprHittedIndex;
  137.     property  BgrSprHittedIndexWas: Cardinal read FBgrSprHittedIndexWas;
  138.     property  BgrSprHittedAt: TPoint read FBgrSprHittedAt;
  139.     property  BgrSpriteWasHitted: Boolean read FBgrSprWasHitted;
  140.     property  BgrSprCaptured: TGraphicControl read FBgrSprCaptured;
  141.     property  BgrSprCapturedIndexWas: Cardinal read FBgrSprCapturedIndexWas;
  142.     property  BgrSpriteCaptured: Boolean read FBgrSpriteCaptured;
  143.     property  BgrSpritesRunning: Boolean read FBgrSpritesRunning write FBgrSpritesRunning default True;
  144.   published
  145.     { Published declarations - can be only class type or properties }
  146.     procedure MChSpriteBgrMouseDown(Sender: TObject; Button: TMouseButton;
  147.       Shift: TShiftState; X, Y: Integer);
  148.     procedure MChSpriteBgrMouseMove(Sender: TObject;
  149.       Shift: TShiftState; X, Y: Integer);
  150.     procedure MChSpriteBgrMouseUp(Sender: TObject; Button: TMouseButton;
  151.       Shift: TShiftState; X, Y: Integer);
  152.     property  Visible;
  153.     property  Height;
  154.     property  Width;
  155.     property  Left;
  156.     property  Top;
  157.     property  AutoSize;
  158.     property  OnMouseDown;
  159.     property  OnMouseMove;
  160.     property  OnMouseUp;
  161.     property  BgrRespondToMouse: Boolean read FBgrRespondToMouse write FBgrRespondToMouse default True;
  162.     property  BgrSearchSprts: Boolean read FBgrSearchSprts write FBgrSearchSprts default True;
  163.   end;
  164.  
  165. function  CheckNotNulRect(Rt: TRect):Boolean;
  166. function  InRect(TP: TPoint; TR: TRect): Boolean;
  167. function  DirtyReg(DOld, DNew: TRect): TDirtyReg;
  168.  
  169. procedure Register;
  170.  
  171. implementation
  172.  
  173. uses
  174.    MChSprt;
  175.  
  176. procedure Register;
  177.   begin
  178.   RegisterComponents('Samples', [TMChSpriteBgr]);
  179.   end;
  180.  
  181. constructor TMChSpriteBgr.Create(AOwner: TComponent);
  182.   begin
  183.   inherited Create(AOwner);
  184.   Width:=1;
  185.   Height:=1;
  186.   AutoSize:=True;
  187.   FBgrSavedBgr:=TBitmap.Create;
  188.   FBgrScreenBuf:=TBitmap.Create;
  189.   FBgrSavedBgr.Width:=Width;
  190.   FBgrSavedBgr.Height:=Height;
  191.   FBgrScreenBuf.Width:=Width;
  192.   FBgrScreenBuf.Height:=Height;
  193.   FBgrSpritesRunning:=True;
  194.   FBgrRespondToMouse:=True;
  195.   FBgrSearchSprts:=True;
  196.   OnMouseDown := MChSpriteBgrMouseDown;
  197.   OnMouseMove := MChSpriteBgrMouseMove;
  198.   OnMouseUp   := MChSpriteBgrMouseUp;
  199.   ControlStyle:=ControlStyle+[csOpaque];
  200.   FBgrStartIdle:=time;
  201.   FBgrSavedOnIdle := Application.OnIdle;
  202.   Application.OnIdle := BgrAppIdle;
  203.   end;
  204.  
  205. destructor TMChSpriteBgr.Destroy;
  206.   begin
  207.   Application.OnIdle := FBgrSavedOnIdle;
  208.   BgrFree;
  209.   inherited Destroy;
  210.   end;
  211.  
  212. procedure TMChSpriteBgr.BgrInit;
  213.   begin
  214.   FBgrSavedBgr.Width:=Width;
  215.   FBgrSavedBgr.Height:=Height;
  216.   FBgrScreenBuf.Width:=Width;
  217.   FBgrScreenBuf.Height:=Height;
  218.   FBgrSavedBgr.Canvas.CopyMode:=cmSrcCopy;
  219.   FBgrScreenBuf.Canvas.CopyMode:=cmSrcCopy;
  220.   FBgrSavedBgr.Canvas.Draw(0,0,Picture.Graphic);
  221.   FBgrScreenBuf.Canvas.Draw(0,0,Picture.Graphic);
  222.   BgrGetAllSprites( (Parent as TComponent) );
  223.   if FBgrRespondToMouse then ControlStyle:=ControlStyle+[csCaptureMouse];
  224.   if Assigned(FBgrOnInit) then FBgrOnInit;
  225.   FBgrInitialized := True;
  226.   end;
  227.  
  228. procedure TMChSpriteBgr.BgrFree;
  229.   begin
  230.   FBgrScreenBuf.Free;
  231.   FBgrSavedBgr.Free;
  232.   FBgrInitialized := False;
  233.   end;
  234.  
  235. procedure TMChSpriteBgr.BgrGetAllSprites(BgrParent: TComponent);
  236.   var
  237.     i, BgrCntr: Cardinal;
  238.   begin
  239.   if not FBgrSearchSprts then Exit;
  240.   FBgrNumOfSprites:=0;
  241.   BgrCntr:=0;
  242.   if BgrParent.ComponentCount>0 then
  243.     begin
  244.     for i:=0 to BgrParent.ComponentCount-1 do
  245.       if BgrParent.Components[i] is TMChSpriteBgr then inc(BgrCntr);
  246.     if BgrCntr<2 then
  247.       begin
  248.       for i:=0 to BgrParent.ComponentCount-1 do
  249.         begin
  250.         if BgrParent.Components[i] is TMChSprite then
  251.           begin
  252.           if FBgrNumOfSprites<BgrMaxSpriteNum then
  253.             begin
  254.             inc(FBgrNumOfSprites);
  255.             FBgrSpriteList[FBgrNumOfSprites]:=(BgrParent.Components[i] as TGraphicControl);
  256.             (FBgrSpriteList[FBgrNumOfSprites] as TMChSprite).SprSetMgr(Self);
  257.             (FBgrSpriteList[FBgrNumOfSprites] as TMChSprite).SprIndex:=FBgrNumOfSprites;
  258.             end;
  259.           end;
  260.         end;
  261.       end;
  262.     end;
  263.   end;
  264.  
  265. function  TMChSpriteBgr.BgrAddTopSpr(Spr: TGraphicControl): Boolean;
  266.   begin
  267.   BgrAddTopSpr:=False;
  268.   if FBgrNumOfSprites<BgrMaxSpriteNum then
  269.     begin
  270.     inc(FBgrNumOfSprites);
  271.     FBgrSpriteList[FBgrNumOfSprites]:=Spr;
  272.     (FBgrSpriteList[FBgrNumOfSprites] as TMChSprite).SprSetMgr(Self);
  273.     (FBgrSpriteList[FBgrNumOfSprites] as TMChSprite).SprIndex:=FBgrNumOfSprites;
  274.     BgrAddTopSpr:=True;
  275.     end;
  276.   end;
  277.  
  278. procedure TMChSpriteBgr.BgrDeleteTopSpr;
  279.   begin
  280.   if FBgrNumOfSprites>0 then
  281.     begin
  282.     (FBgrSpriteList[FBgrNumOfSprites] as TMChSprite).SprUnsetMgr;
  283.     dec(FBgrNumOfSprites);
  284.     end;
  285.   end;
  286.  
  287. procedure TMChSpriteBgr.BgrSprExchangeZ(Spr1, Spr2: TGraphicControl);
  288.   begin
  289.   BgrSprIndexExchangeZ( (Spr1 as TMChSprite).SprIndex, (Spr2 as TMChSprite).SprIndex );
  290.   end;
  291.  
  292. procedure TMChSpriteBgr.BgrSprShiftZ(SprFrom, SprDest: TGraphicControl);
  293.   begin
  294.   BgrSprIndexShiftZ( (SprFrom as TMChSprite).SprIndex, (SprDest as TMChSprite).SprIndex );
  295.   end;
  296.  
  297. procedure TMChSpriteBgr.BgrSprExchangeToTop(Spr: TGraphicControl);
  298.   begin
  299.   BgrSprIndexExchangeToTop( (Spr as TMChSprite).SprIndex );
  300.   end;
  301.  
  302. procedure TMChSpriteBgr.BgrSprShiftToTop(Spr: TGraphicControl);
  303.   begin
  304.   BgrSprIndexShiftToTop( (Spr as TMChSprite).SprIndex );
  305.   end;
  306.  
  307. procedure TMChSpriteBgr.BgrSprIndexExchangeZ(SprI1, SprI2: Cardinal);
  308.   var
  309.     i: Cardinal;
  310.   begin
  311.   if (SprI1>FBgrNumOfSprites) or (SprI2>FBgrNumOfSprites) or (SprI1=SprI2) or 
  312.      (SprI1=0) or (SprI2=0) then exit;
  313.   BgrPause:=True;
  314.   FBgrSprTmp:=FBgrSpriteList[SprI1];
  315.   FBgrSpriteList[SprI1]:=FBgrSpriteList[SprI2];
  316.   (FBgrSpriteList[SprI1] as TMChSprite).SprIndex:=SprI1;
  317.   (FBgrSpriteList[SprI1] as TMChSprite).SprRepaint:=True;
  318.   FBgrSpriteList[Spri2]:=FBgrSprTmp;
  319.   (FBgrSpriteList[Spri2] as TMChSprite).SprIndex:=SprI2;
  320.   (FBgrSpriteList[SprI2] as TMChSprite).SprRepaint:=True;
  321.   BgrPause:=False;
  322.   end;
  323.  
  324. procedure TMChSpriteBgr.BgrSprIndexShiftZ(SprIFrom, SprIDest: Cardinal);
  325.   var
  326.     i, SprILo, SprIHi: Cardinal;
  327.   begin
  328.   if (SprIFrom>FBgrNumOfSprites) or (SprIDest>FBgrNumOfSprites) or (SprIFrom=SprIDest) or 
  329.      (SprIFrom=0) or (SprIDest=0) then exit;
  330.   if SprIFrom>SprIDest then
  331.     begin
  332.     SprILo:=SprIDest;
  333.     SprIHi:=SprIFrom;
  334.     end
  335.   else
  336.     begin
  337.     SprILo:=SprIFrom;
  338.     SprIHi:=SprIDest;
  339.     end;
  340.   BgrPause:=True;
  341.   if SprIFrom<SprIDest then
  342.     begin
  343.     FBgrSprTmp:=FBgrSpriteList[SprIFrom];
  344.     i:=SprIFrom;
  345.     while i<SprIDest do
  346.       begin
  347.       FBgrSpriteList[i]:=FBgrSpriteList[i+1];
  348.       (FBgrSpriteList[i] as TMChSprite).SprIndex:=i;
  349.       (FBgrSpriteList[i] as TMChSprite).SprRepaint:=True;
  350.       inc(i);
  351.       end;
  352.     FBgrSpriteList[i]:=FBgrSprTmp;
  353.     (FBgrSpriteList[i] as TMChSprite).SprIndex:=i;
  354.     (FBgrSpriteList[i] as TMChSprite).SprRepaint:=True;
  355.     end
  356.   else
  357.     begin
  358.     FBgrSprTmp:=FBgrSpriteList[SprIFrom];
  359.     i:=SprIFrom;
  360.     while i>SprIDest do
  361.       begin
  362.       FBgrSpriteList[i]:=FBgrSpriteList[i-1];
  363.       (FBgrSpriteList[i] as TMChSprite).SprIndex:=i;
  364.       (FBgrSpriteList[i] as TMChSprite).SprRepaint:=True;
  365.       dec(i);
  366.       end;
  367.     FBgrSpriteList[i]:=FBgrSprTmp;
  368.     (FBgrSpriteList[i] as TMChSprite).SprIndex:=i;
  369.     (FBgrSpriteList[i] as TMChSprite).SprRepaint:=True;
  370.     end;
  371.     BgrPause:=False;
  372.   end;
  373.  
  374. procedure TMChSpriteBgr.BgrSprIndexExchangeToTop(SprI: Cardinal);
  375.   begin
  376.   if (SprI<FBgrNumOfSprites) and (SprI>0) then BgrSprIndexExchangeZ(SprI, FBgrNumOfSprites);
  377.   end;
  378.  
  379. procedure TMChSpriteBgr.BgrSprIndexShiftToTop(SprI: Cardinal);
  380.   begin
  381.   if (SprI<FBgrNumOfSprites) and (SprI>0) then BgrSprIndexShiftZ(SprI, FBgrNumOfSprites);
  382.   end;
  383.  
  384. procedure TMChSpriteBgr.BgrSetBackground(Bg: TBitmap);
  385.   var
  386.     i: Cardinal;
  387.   begin
  388.   Width :=Bg.Width;
  389.   Height:=Bg.Height;
  390.   FBgrSavedBgr.Width   := Bg.Width;
  391.   FBgrSavedBgr.Height  := Bg.Height;
  392.   FBgrScreenBuf.Width  := Bg.Width;
  393.   FBgrScreenBuf.Height := Bg.Height;
  394.   FBgrSavedBgr.Canvas.CopyMode:=cmSrcCopy;
  395.   FBgrSavedBgr.Canvas.Draw(0,0,Bg);
  396.   FBgrScreenBuf.Canvas.CopyMode:=cmSrcCopy;
  397.   FBgrScreenBuf.Canvas.Draw(0,0,FBgrSavedBgr);
  398.   Picture.Graphic:=Bg;
  399.   Canvas.Draw(0,0,FBgrScreenBuf);
  400.   if FBgrNumOfSprites>0 then
  401.     for i:=1 to FBgrNumOfSprites do (FBgrSpriteList[i] as TMChSprite).SprRepaint:=True;
  402. end;
  403.  
  404. procedure TMChSpriteBgr.BgrRestoreBgr;
  405.   begin
  406.   if not FBgrInitialized then BgrInit;
  407.   if Assigned(FBgrSavedBgr) and not FBgrSavedBgr.Empty then
  408.     begin
  409.     Canvas.CopyMode := cmSrcCopy;
  410.     Canvas.CopyRect(Rect(0,0,Width,Height),
  411.                     FBgrSavedBgr.Canvas,
  412.                     Rect(0,0,FBgrSavedBgr.Width,FBgrSavedBgr.Height) );
  413.     end;
  414.   end;
  415.  
  416. procedure TMChSpriteBgr.BgrRestoreScreen;
  417.   var
  418.     i: Cardinal;
  419.   begin
  420.   if not FBgrInitialized then BgrInit;
  421.   if Assigned(FBgrScreenBuf) and (not FBgrScreenBuf.Empty) then
  422.     begin
  423.     Canvas.CopyMode := cmSrcCopy;
  424.     Canvas.CopyRect(Rect(0,0,Width,Height),
  425.                     FBgrScreenBuf.Canvas,
  426.                     Rect(0,0,FBgrScreenBuf.Width,FBgrScreenBuf.Height) );
  427.     if FBgrNumOfSprites>0 then
  428.       for i:=1 to FBgrNumOfSprites do (FBgrSpriteList[i] as TMChSprite).SprRepaint:=True;
  429.     end;
  430.   end;
  431.  
  432. procedure TMChSpriteBgr.BgrEraseBufRect(Rc:TRect);
  433.   begin
  434.   if not FBgrInitialized then BgrInit;
  435.   if Assigned(FBgrScreenBuf) and not FBgrScreenBuf.Empty and
  436.      Assigned(FBgrSavedBgr) and not FBgrSavedBgr.Empty then
  437.     begin
  438.     FBgrScreenBuf.Canvas.CopyMode := cmSrcCopy;
  439.     FBgrScreenBuf.Canvas.CopyRect(Rc,
  440.                     FBgrSavedBgr.Canvas,
  441.                     Rc);
  442.     end;
  443.   end;
  444.  
  445. procedure TMChSpriteBgr.BgrUpdateDirtyReg(Dr: TDirtyReg);
  446.   var
  447.     URect: TRect;
  448.   begin
  449.   if not FBgrInitialized then BgrInit;
  450.   if 0<>IntersectRect(URect,Dr.Old,Dr.New) then
  451.     begin
  452.     if 0<>UnionRect(URect, Dr.Old,Dr.New) then
  453.       if Assigned(FBgrScreenBuf) and not FBgrScreenBuf.Empty then
  454.         begin
  455.         if CheckNotNulRect(URect) then
  456.           begin
  457.           Canvas.CopyMode := cmSrcCopy;
  458.           Canvas.CopyRect(URect,FBgrScreenBuf.Canvas,URect);
  459.           end;
  460.         end;
  461.     end
  462.   else
  463.     begin
  464.     if Assigned(FBgrScreenBuf) and not FBgrScreenBuf.Empty then
  465.       begin
  466.       if CheckNotNulRect(Dr.Old) or CheckNotNulRect(Dr.New) then
  467.         begin
  468.         Canvas.CopyMode := cmSrcCopy;
  469.         if CheckNotNulRect(Dr.Old) then Canvas.CopyRect(Dr.Old,FBgrScreenBuf.Canvas,Dr.Old);
  470.         if CheckNotNulRect(Dr.New) then Canvas.CopyRect(Dr.New,FBgrScreenBuf.Canvas,Dr.New);
  471.         end;
  472.       end;
  473.     end;
  474.   end;
  475.  
  476. procedure TMChSpriteBgr.BgrUpdateDirtyRegToCanvas(Dr: TDirtyReg);
  477.   var
  478.     URect,UURect,DDrOld,DDrNew: TRect;
  479.     ImgPos: TPoint;
  480.   begin
  481.   ImgPos.x:= Left;
  482.   ImgPos.y:= Top;
  483.   if 0<>IntersectRect(URect,Dr.Old,Dr.New) then
  484.     begin
  485.     if 0<>UnionRect(URect, Dr.Old,Dr.New) then
  486.       if Assigned(FBgrScreenBuf) and not FBgrScreenBuf.Empty then
  487.         begin
  488.         if CheckNotNulRect(URect) then
  489.           begin
  490.           UURect:=Rect(ImgPos.x+URect.left,ImgPos.y+URect.Top,ImgPos.x+URect.right,ImgPos.y+URect.bottom);
  491.           (Parent as TForm).Canvas.CopyMode := cmSrcCopy;
  492.           (Parent as TForm).Canvas.CopyRect(UURect,FBgrScreenBuf.Canvas,URect);
  493.           end;
  494.         end;
  495.     end
  496.   else
  497.     begin
  498.     if Assigned(FBgrScreenBuf) and not FBgrScreenBuf.Empty then
  499.       begin
  500.       if CheckNotNulRect(Dr.Old) or CheckNotNulRect(Dr.New) then
  501.         begin
  502.         DDrOld:=Rect(ImgPos.x+Dr.Old.left,ImgPos.y+Dr.Old.Top,ImgPos.x+Dr.Old.right,ImgPos.y+Dr.Old.bottom);
  503.         DDrNew:=Rect(ImgPos.x+Dr.New.left,ImgPos.y+Dr.New.Top,ImgPos.x+Dr.New.right,ImgPos.y+Dr.New.bottom);
  504.         (Parent as TForm).Canvas.CopyMode := cmSrcCopy;
  505.         if CheckNotNulRect(Dr.Old) then (Parent as TForm).Canvas.CopyRect(DDrOld,FBgrScreenBuf.Canvas,Dr.Old);
  506.         if CheckNotNulRect(Dr.New) then (Parent as TForm).Canvas.CopyRect(DDrNew,FBgrScreenBuf.Canvas,Dr.New);
  507.         end;
  508.       end;
  509.     end;
  510.   end;
  511.  
  512. procedure TMChSpriteBgr.BgrScreenBufDrawMaskPaint(LeftTop: TPoint; BitMask, Bitmp: TBitmap);
  513.   begin
  514.   FBgrScreenBuf.Canvas.CopyMode := cmSrcAnd;
  515.   FBgrScreenBuf.Canvas.Draw(LeftTop.x,LeftTop.y,BitMask);
  516.   FBgrScreenBuf.Canvas.CopyMode := cmSrcPaint;
  517.   FBgrScreenBuf.Canvas.Draw(LeftTop.x,LeftTop.y,Bitmp);
  518.   end;
  519.  
  520. procedure TMChSpriteBgr.BgrScreenBufStretchMaskPaint(RectToPaintTo: TRect; BitMask, Bitmp: TBitmap);
  521.   begin
  522.   FBgrScreenBuf.Canvas.CopyMode:=cmSrcAnd;
  523.   FBgrScreenBuf.Canvas.StretchDraw(RectToPaintTo,BitMask);
  524.   FBgrScreenBuf.Canvas.CopyMode:=cmSrcPaint;
  525.   FBgrScreenBuf.Canvas.StretchDraw(RectToPaintTo,Bitmp);
  526.   end;
  527.  
  528. procedure TMChSpriteBgr.BgrScreenBufDrawRect(LeftTop: TPoint; Bitmp: TBitmap);
  529.   begin
  530.   FBgrScreenBuf.Canvas.CopyMode := cmSrcCopy;
  531.   FBgrScreenBuf.Canvas.Draw(LeftTop.x,LeftTop.y,Bitmp);
  532.   end;
  533.  
  534. procedure TMChSpriteBgr.BgrScreenBufGetRect(RectCopyTo: TRect; BitmpCopyTo: TBitmap; RectCopyFrom: TRect);
  535.   begin
  536.   BitmpCopyTo.Canvas.CopyMode:=cmSrcCopy;
  537.   BitmpCopyTo.Canvas.CopyRect(RectCopyTo,FBgrScreenBuf.Canvas,RectCopyFrom); 
  538.   end;
  539.  
  540. procedure TMChSpriteBgr.BgrHideInBuf;
  541.   var
  542.     i: Cardinal;
  543.   begin
  544.   if FBgrNumOfSprites<1 then exit;
  545.   for i:=1 to FBgrNumOfSprites do
  546.     begin
  547.     (FBgrSpriteList[i] as TMChSprite).SprHideTmp;
  548.     end;
  549.   end;
  550.  
  551. procedure TMChSpriteBgr.BgrShowInBuf(JT: TDateTime);
  552.   var
  553.     i: Cardinal;
  554.   begin
  555.   if FBgrNumOfSprites<1 then exit;
  556.   for i:=1 to FBgrNumOfSprites do
  557.     begin
  558.     (FBgrSpriteList[i] as TMChSprite).SprShowAtTime(JT);
  559.     end;
  560.   end;
  561.  
  562. procedure TMChSpriteBgr.BgrUpdateBgrCanvas;
  563.   var
  564.     i: Cardinal;
  565.   begin
  566.   if FBgrNumOfSprites<1 then exit;
  567.   for i:=1 to FBgrNumOfSprites do
  568.     begin
  569.     BgrUpdateDirtyReg( (FBgrSpriteList[i] as TMChSprite).SprGetDirty );
  570.     end;
  571.   end;
  572.  
  573.  
  574. procedure TMChSpriteBgr.BgrAppIdle(Sender: TObject; var Done: Boolean);
  575.   var
  576.     i: Cardinal;
  577.     JumpTime, TestTime: TDateTime;
  578.   begin
  579.   if not FBgrInitialized then BgrInit;
  580.   try
  581.     if FBgrSpritesRunning and not BgrPause and (FBgrNumOfSprites>0) then
  582.       begin
  583.       FBgrInAppIdle:=True;
  584.       Done := False;
  585.       BgrHideInBuf;
  586.       JumpTime:=time;
  587.       BgrCollisionCheck(JumpTime);
  588.       BgrShowInBuf(JumpTime);
  589.       BgrUpdateBgrCanvas;
  590.       end;
  591.   finally
  592.       TestTime:=time;
  593.       if FBgrIdleCntr<100 then
  594.         begin
  595.         inc(FBgrIdleCntr);
  596.         if (FBgrIdleCntr>=10) and ((TestTime-FBgrStartIdle)*24.0*60.0*60.0>1.0) 
  597.           then FBgrCntsPerSec:=FBgrIdleCntr/((time-FBgrStartIdle)*24.0*60.0*60.0);
  598.         end
  599.       else
  600.         begin
  601.         if ((TestTime-FBgrStartIdle)*24.0*60.0*60.0>1.0) then
  602.           FBgrCntsPerSec:=FBgrIdleCntr/((TestTime-FBgrStartIdle)*24.0*60.0*60.0);
  603.         FBgrStartIdle:=time;
  604.         FBgrIdleCntr:=1;
  605.         end;
  606.       FBgrInAppIdle:=False;
  607.       if Assigned(FBgrSavedOnIdle) then
  608.         if not (Sender is TMChSprite) then FBgrSavedOnIdle(Self, Done);
  609.     end;
  610.   end;
  611.  
  612. function  CheckNotNulRect(Rt: TRect):Boolean;
  613.   begin
  614.   if (Rt.Left=0) and (Rt.Top=0) and (Rt.Right=0) and (Rt.Bottom=0) then
  615.     CheckNotNulRect:=False
  616.   else CheckNotNulRect:=True;
  617.   end;
  618.  
  619. function  InRect(TP: TPoint; TR: TRect): Boolean;
  620.   begin
  621.   if (
  622.      ((TR.Left< TR.Right) and (TR.Left<=TP.x) and (TP.x<=TR.Right)) or
  623.      ((TR.Left>=TR.Right) and (TR.Left>=TP.x) and (TP.x>=TR.Right))
  624.      ) and
  625.      (
  626.      ((TR.Top< TR.Bottom) and (TR.Top <=TP.y) and (TP.y<=TR.Bottom)) or
  627.      ((TR.Top>=TR.Bottom) and (TR.Top >=TP.y) and (TP.y>=TR.Bottom))
  628.      )
  629.      then InRect:=True
  630.      else InRect:=False;
  631.   end;
  632.  
  633. function  DirtyReg(DOld, DNew: TRect): TDirtyReg;
  634.   begin
  635.   DirtyReg.Old:=DOld;
  636.   DirtyReg.New:=DNew;
  637.   end;
  638.  
  639. procedure TMChSpriteBgr.MChSpriteBgrMouseDown(Sender: TObject;
  640.   Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  641.   var
  642.     i: Cardinal;
  643.   begin
  644.   if FBgrNumOfSprites<1 then exit;
  645.   if FBgrRespondToMouse and (Button=mbLeft) then
  646.     begin
  647.     for i:=FBgrNumOfSprites downto 1 do
  648.       begin
  649.       if (FBgrSpriteList[i] as TMChSprite).SprHitTest(Point(X,Y)) then
  650.         begin
  651.         FBgrSprHitted:=FBgrSpriteList[i];
  652.         FBgrSprHittedWas:=FBgrSprHitted;
  653.         FBgrSprHittedIndex:=i;
  654.         FBgrSprHittedIndexWas:=i;
  655.         FBgrSprHittedAt:=(FBgrSprHitted as TMChSprite).SprHitAt(Point(X,Y));
  656.         FBgrSprWasHitted:=True;
  657.         Break;
  658.         end;
  659.       end;
  660.     if Assigned(FBgrSprHitted) and (FBgrSprHitted as TMChSprite).SprDragable then
  661.       begin
  662.       FBgrSprCaptured:=FBgrSprHitted;
  663.       FBgrSprCapturedIndexWas:=FBgrSprHittedIndex;
  664.       FBgrSpriteCaptured:=True;
  665.       BgrSprIndexExchangeToTop(FBgrSprHittedIndex);
  666.       (FBgrSprCaptured as TMChSprite).SprPaused:=True;
  667.       end;
  668.     end;
  669.   end;
  670.  
  671. procedure TMChSpriteBgr.MChSpriteBgrMouseMove(Sender: TObject;
  672.   Shift: TShiftState; X, Y: Integer);
  673.   begin
  674.   if FBgrSpriteCaptured then
  675.     begin
  676.     (FBgrSprCaptured as TMChSprite).SprShowAt(Point(X-FBgrSprHittedAt.x,Y-FBgrSprHittedAt.y));
  677.     end;
  678.   end;
  679.  
  680. procedure TMChSpriteBgr.MChSpriteBgrMouseUp(Sender: TObject;
  681.   Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  682.   begin
  683.   if (Button=mbLeft) and FBgrSprWasHitted then
  684.     begin
  685.     FBgrSprHitted:=nil;
  686.     FBgrSprHittedIndex:=0;
  687.     FBgrSprHittedAt:=NulPoint;
  688.     FBgrSprWasHitted:=False;
  689.     if FBgrSpriteCaptured then
  690.       begin
  691.       if FBgrSprCapturedIndexWas<FBgrNumOfSprites then BgrSprIndexExchangeZ(FBgrNumOfSprites,FBgrSprCapturedIndexWas);
  692.       (FBgrSprCaptured as TMChSprite).SprPaused:=False;
  693.       FBgrSpriteCaptured:=False;
  694.       FBgrSprCaptured:=nil;
  695.       FBgrSprCapturedIndexWas:=0;
  696.       end;
  697.     end;
  698.   end;
  699.  
  700. procedure TMChSpriteBgr.BgrCollisionCheck(AtTime: TDateTime);
  701.   var
  702.     i,j: Cardinal;
  703.     BreakAll: Boolean;
  704.     SprCollided: array[1..BgrMaxSpriteNum] of Boolean;
  705.   begin
  706.   if FBgrNumOfSprites<=1 then exit;
  707.   BreakAll:=False;
  708.   for i:=1 to FBgrNumOfSprites do SprCollided[i]:=False;
  709.   for i:=FBgrNumOfSprites downto 2 do
  710.     begin
  711.     if (FBgrSpriteList[i] as TMChSprite).SprColliding then
  712.       begin
  713.       if Assigned((FBgrSpriteList[i] as TMChSprite).FSprOnBorder) and
  714.          (FBgrSpriteList[i] as TMChSprite).SprCheckBorders(AtTime) then
  715.            (FBgrSpriteList[i] as TMChSprite).SprOnBorder(AtTime);
  716.       for j:=i-1 downto 1 do
  717.         begin
  718.         if (FBgrSpriteList[i] as TMChSprite).SprCheckCollision((FBgrSpriteList[j] as TMChSprite),AtTime) then
  719.           begin
  720.           SprCollided[i]:=True;
  721.           SprCollided[j]:=True;
  722.           if Assigned((FBgrSpriteList[i] as TMChSprite).FSprOnCollide) then
  723.             (FBgrSpriteList[i] as TMChSprite).SprOnCollide((FBgrSpriteList[j] as TMChSprite),AtTime)
  724.           else 
  725.             if Assigned((FBgrSpriteList[j] as TMChSprite).FSprOnCollide) then 
  726.               (FBgrSpriteList[j] as TMChSprite).SprOnCollide((FBgrSpriteList[i] as TMChSprite),AtTime);
  727.           if ((FBgrSpriteList[i] as TMChSprite).SprCollisionMask) or
  728.              ((FBgrSpriteList[j] as TMChSprite).SprCollisionMask)
  729.             then
  730.             begin
  731.             BreakAll:=True;
  732.             Break; {Detect only single collision - SprOnCollide can change FBgrSpriteList }
  733.             end;
  734.           end;
  735.         end;
  736.         if (not SprCollided[i]) and Assigned((FBgrSpriteList[i] as TMChSprite).FSprNoCollide) then
  737.                 (FBgrSpriteList[i] as TMChSprite).SprNoCollide(AtTime);
  738.       end;
  739.     if BreakAll then Break
  740.     else if (i=2) and (not SprCollided[1]) and (FBgrSpriteList[1] as TMChSprite).SprColliding and
  741.            Assigned((FBgrSpriteList[1] as TMChSprite).FSprNoCollide)
  742.       then (FBgrSpriteList[1] as TMChSprite).SprNoCollide(AtTime);
  743.     end;
  744.   end;
  745.  
  746. end.
  747.